package com.retail.bbq.cola.service.impl;

import com.retail.bbq.cola.enums.ErrorCodeEnum;
import com.retail.bbq.cola.exception.BusinessException;
import com.retail.bbq.cola.service.CommonService;
import com.retail.bbq.cola.utils.DateUtil;
import com.retail.bbq.cola.vo.request.LotteryTimeRequest;
import com.retail.bbq.cola.vo.response.LotteryTimeResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommonServiceImpl implements CommonService {
    public static final List<Integer> points = Arrays.asList(2,9,19,49);

    @Override
    public LotteryTimeResponse lotteryTimeQuery(LotteryTimeRequest request) {
        if(CollectionUtils.isEmpty(request.getLotteryDt()) || request.getLotteryDt().size() != request.getLotteryNum()){
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR);
        }

        List<Date> lotteryDateList = request.getLotteryDt().stream()
                .map(Instant::parse).sorted()
                .map(Date::from)
                .collect(Collectors.toList());;

        LotteryTimeResponse lotteryTimeResponse = new LotteryTimeResponse();
        lotteryTimeResponse.setCustomerId(request.getCustomerId());

        List<LotteryTimeRequest.ReducePointChangeDetail> reducePointChangeDetailList = request.getReducePointChangeDetailList();
        lotteryTimeResponse.setLotteryInfoList(findThresholdCrossingDetails(reducePointChangeDetailList, points, lotteryDateList));
        return lotteryTimeResponse;
    }


    public List<LotteryTimeResponse.LotteryInfo> findThresholdCrossingDetails(
            List<LotteryTimeRequest.ReducePointChangeDetail> details,
            List<Integer> thresholds,
            List<Date> lotteryDateList) {

        if (details == null || thresholds == null) {
            return Collections.emptyList();
        }

        // 1. 按updateTime升序排序
        List<LotteryTimeRequest.ReducePointChangeDetail> sortedDetails = details.stream()
                .sorted(Comparator.comparing(d -> Instant.parse(d.getUpdateTime())))
                .collect(Collectors.toList());

        // 2. 准备结果集合和阈值队列（按升序排列）
        List<LotteryTimeResponse.LotteryInfo> result = new ArrayList<>();
        PriorityQueue<Integer> thresholdQueue = new PriorityQueue<>(thresholds);

        int accumulatedPoints = 0;
        int currentThreshold = thresholdQueue.isEmpty() ? Integer.MAX_VALUE : thresholdQueue.peek();
        int index = 1;
        // 3. 遍历排序后的明细
        for (LotteryTimeRequest.ReducePointChangeDetail detail : sortedDetails) {
            accumulatedPoints += detail.getPoint();
            while (accumulatedPoints >= currentThreshold && !thresholdQueue.isEmpty()) {
                boolean isLottery = lotteryDateList.size() <= index;
                LotteryTimeResponse.LotteryInfo lotteryInfo = new LotteryTimeResponse.LotteryInfo();
                lotteryInfo.setIndex(index);
                lotteryInfo.setPointGetDt(detail.getUpdateTime());
                lotteryInfo.setLotteryDt(isLottery ? DateUtil.dateToStr(lotteryDateList.get(index-1)) : "-");
                lotteryInfo.setLotteryStatus(isLottery ? 2:1);
                result.add(lotteryInfo);
                thresholdQueue.poll();
                currentThreshold = thresholdQueue.isEmpty() ? Integer.MAX_VALUE : thresholdQueue.peek();
            }

            if (thresholdQueue.isEmpty()) {
                break; // 所有阈值都已处理
            }
        }

        return result;
    }
}
